package com.more.offer.threadtest.reentrantlocktest;

import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;

/**
 * @author pinoc
 * @date 2021/11/15
 * @description 使用ReentrantLock 对于读多写少场景性能交叉，使用读写分离优化自定义线程安全的list
 */
public class ReadWriteLockList {

	private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	private final Lock readLock = lock.readLock();
	private final Lock writeLock = lock.writeLock();
	private ArrayList<String> array = new ArrayList<>();

	public void add(String e) {
		writeLock.lock();
		try{
			array.add(e);
		}  finally {
			writeLock.unlock();
		}
	}

	public void remove(String e) {
		writeLock.lock();
		try {
			if(this.array == null || array.size() == 0) {
				return ;
			}
			array.remove(e);
		} finally {
			writeLock.unlock();
		}
	}

	public String get(int index) {
		readLock.lock();
		try {
			if(this.array == null || array.size() == 0) {
				return "";
			}
			return array.get(index);
		} finally {
			readLock.unlock();
		}
	}

	//测试
	public static void main(String[] args) throws InterruptedException {
		ReadWriteLockList readWriteLockList = new ReadWriteLockList();
		for (int i = 0; i < 5; i++) {
			new Thread(()->{
				while (true) {
					System.out.println(Thread.currentThread().getName() + " : " + readWriteLockList.get(0));
				}
			}).start();
		}
		Thread.sleep(3000);
		readWriteLockList.add("123");
		Thread.sleep(3000);
		readWriteLockList.remove("123");
		Thread.sleep(3000);
		readWriteLockList.add("ssss");
		Thread.sleep(3000);
		readWriteLockList.remove("ssss");
		Thread.sleep(3000);
		readWriteLockList.add("go");
	}
}
